package com.log4jviewer.ui.preferences.additional;

import java.io.File;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;

import com.log4jviewer.Activator;

/**
 * Class defines additional preferences constants and default settings values for log foreground and background colors,
 * font, usage image instead of text. Provides list of log level display preference model.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a>
 */
public final class LogDisplayPreferences {

    private static IPreferenceStore store = Activator.getInstance().getPreferenceStore();

    private static LogColorSettings logColorSettings = new LogColorSettings();

    private static LogFontSettings logFontSettings = new LogFontSettings();

    private LogDisplayPreferences() {
        // no code
    }

    public static LogColorSettings getLogColorSettings() {
        return logColorSettings;
    }

    public static LogFontSettings getLogFontSettings() {
        return logFontSettings;
    }

    public static final class LogColorSettings {

        private static final String LEVEL_IMAGE_INSTEAD_OF_TEXT_ID = "log_level_image_text";

        private static final boolean LEVEL_IMAGE_ISTEAD_OF_TEXT_DEFAULT = true;

        private static final int LEVELS_COUNT = 5;

        private LogLevelDisplayModel[] logLevelDisplayModelList;

        public String getId() {
            return LEVEL_IMAGE_INSTEAD_OF_TEXT_ID;
        }

        public boolean getDefault() {
            return LEVEL_IMAGE_ISTEAD_OF_TEXT_DEFAULT;
        }

        public LogLevelDisplayModel[] getLogLevelDisplayModelList() {
            if (logLevelDisplayModelList == null) {
                createLevelDisplayModelList();
            }
            return logLevelDisplayModelList;
        }

        public boolean isLevelImageInsteadOfText() {
            return store.getBoolean(LEVEL_IMAGE_INSTEAD_OF_TEXT_ID);
        }

        public void setLevelImageInsteadOfText(final boolean isLevelImageInsteadOfText) {
            store.setValue(LEVEL_IMAGE_INSTEAD_OF_TEXT_ID, isLevelImageInsteadOfText);
        }

        private void createLevelDisplayModelList() {
            logLevelDisplayModelList = new LogLevelDisplayModel[LEVELS_COUNT];

            for (int i = 0; i < LEVELS_COUNT; i++) {
                String levelName = LogLevel.values()[i].getName();
                Image image = LogLevel.values()[i].getImage();

                LogLevelDisplayModel logLevelDisplayModel = new LogLevelDisplayModel(levelName, image);

                RGB foreground = PreferenceConverter.getColor(store, Foreground.values()[i].getId());
                logLevelDisplayModel.setForeground(foreground);

                RGB background = PreferenceConverter.getColor(store, Background.values()[i].getId());
                logLevelDisplayModel.setBackground(background);

                logLevelDisplayModelList[i] = logLevelDisplayModel;
            }
        }

        public void saveSettings() {
            for (int i = 0; i < LEVELS_COUNT; i++) {
                PreferenceConverter.setValue(store, Foreground.values()[i].getId(),
                        logLevelDisplayModelList[i].getForeground());
                PreferenceConverter.setValue(store, Background.values()[i].getId(),
                        logLevelDisplayModelList[i].getBackground());
            }
        }
    }

    public static final class LogFontSettings {

        private static final String FONT_SIZE_ID = "log_font_size";

        private static final int FONT_SIZE_DEFAULT = 11;

        public String getId() {
            return FONT_SIZE_ID;
        }

        public int getDefault() {
            return FONT_SIZE_DEFAULT;
        }

        public int getFontSize() {
            return store.getInt(FONT_SIZE_ID);
        }

        public void setFontSize(final int fontSize) {
            store.setValue(FONT_SIZE_ID, fontSize);
        }
    }

    public static enum LogLevel {

        DEBUG("DEBUG", "icons" + File.separator + "debug_level.png"),
        INFO("INFO", "icons" + File.separator + "info_level.png"),
        WARN("WARN", "icons" + File.separator + "warn_level.png"),
        ERROR("ERROR", "icons" + File.separator + "error_level.png"),
        FATAL("FATAL", "icons" + File.separator + "error_level.png");

        private String name;

        private Image image;

        private LogLevel(final String name, final String imagePath) {
            this.name = name;
//                      String absoluteImagePath = "file:" + Activator.getAbsolutePath(imagePath);
            image = Activator.getImageDescriptor(imagePath).createImage();
        }

        public String getName() {
            return name;
        }

        public Image getImage() {
            return image;
        }
    }

    public static enum Foreground {

        DEBUG_COLOR("foreground_debug_color", new RGB(0, 0, 0)),
        INFO_COLOR("foreground_info_color", new RGB(0, 255, 0)),
        WARN_COLOR("foreground_warn_color", new RGB(255, 128, 0)),
        ERROR_COLOR("foreground_error_color", new RGB(255, 0, 0)),
        FATAL_COLOR("foreground_fatal_color", new RGB(255, 0, 0));

        private String id;

        private RGB defaultColor;

        private Foreground(final String id, final RGB defaultColor) {
            this.id = id;
            this.defaultColor = defaultColor;
        }

        public String getId() {
            return id;
        }

        public RGB getDefaultColor() {
            RGB defaultColorCopy = new RGB(defaultColor.red, defaultColor.green, defaultColor.blue);
            return defaultColorCopy;
        }
    }

    public static enum Background {

        DEBUG_COLOR("background_debug_color", new RGB(237, 236, 235)),
        INFO_COLOR("background_info_color", new RGB(237, 236, 235)),
        WARN_COLOR("background_warn_color", new RGB(237, 236, 235)),
        ERROR_COLOR("background_error_color", new RGB(237, 236, 235)),
        FATAL_COLOR("background_fatal_color", new RGB(237, 236, 235));

        private String id;

        private RGB defaultColor;

        private Background(final String id, final RGB defaultColor) {
            this.id = id;
            this.defaultColor = defaultColor;
        }

        public String getId() {
            return id;
        }

        public RGB getDefaultColor() {
            RGB defaultColorCopy = new RGB(defaultColor.red, defaultColor.green, defaultColor.blue);
            return defaultColorCopy;
        }
    }
}